package com.laobiao.file_netty_lib.netty.server.handler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.laobiao.file_netty_lib.content.LoggerUtil;
import com.laobiao.file_netty_lib.netty.server.ServerApplication;
import com.laobiao.file_netty_lib.netty.server.ServerBusiness;
import com.laobiao.file_netty_lib.netty.server.ServerHandler;
import com.laobiao.file_netty_lib.packet.BasePacket;
import com.laobiao.file_netty_lib.packet.command.ResoultCommand;
import com.laobiao.file_netty_lib.packet.command.download.ClientFileDownloadCommand;
import com.laobiao.file_netty_lib.packet.command.download.ServerFileDownloadResoutCommand;
import com.laobiao.file_netty_lib.packet.data.BaseDataPacket;

import io.netty.channel.ChannelHandlerContext;

public class ServerDownloadBusiness implements ServerBusiness{
	private final Logger logger =LoggerUtil.getLogger(ServerDownloadBusiness.class);

	/**
	 * 客户端文件下载命令
	 */
	private ClientFileDownloadCommand clientFileDownloadCommand;
	
	/**
	 * 服务端反馈的文件详情命令
	 */
	private ServerFileDownloadResoutCommand serverFileDownloadResoutCommand;
	
	/**
	 * 文件读取通道
	 */
	private RandomAccessFile fileRead;
	
	private boolean stop=false;
	
	public ServerDownloadBusiness(ChannelHandlerContext ctx,ClientFileDownloadCommand clientFileDownloadCommand) {
		this.clientFileDownloadCommand=clientFileDownloadCommand;
		String loadFilePath = clientFileDownloadCommand.getRemoteFilePath();
		loadFilePath=loadFilePath.replace("\\", "/");
		if(!loadFilePath.startsWith("/")) {
			loadFilePath="/"+loadFilePath;
		}
		File loadFile = new File(ServerApplication.getLocalBaseDir().getAbsolutePath()+loadFilePath);
		try {
			serverFileDownloadResoutCommand=new ServerFileDownloadResoutCommand(loadFile,clientFileDownloadCommand.getBusinessGroup());
			fileRead=new RandomAccessFile(loadFile, "r");
			pushFileDatas(ctx);
		} catch (Exception e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			ResoultCommand command=new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_PUSHFILE,"文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】读取错误！"+e.getMessage(),false,clientFileDownloadCommand.getBusinessGroup());
			ctx.writeAndFlush(command);
			ServerHandler.cleanBusinessCommands(ctx.channel().remoteAddress().toString()+"_"+clientFileDownloadCommand.getBusinessGroup());
			logger.log(Level.WARNING, "文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】读取错误！", e);
			close();
		}
	}
	
	/**
	 * 开始推送数据
	 * @param ctx
	 */
	private void pushFileDatas(ChannelHandlerContext ctx) {
		ctx.writeAndFlush(serverFileDownloadResoutCommand);
		long surplusLength=serverFileDownloadResoutCommand.getFileSize();
		byte[] b=new byte[(int)Math.min(1015,surplusLength)];
		try {
			while (fileRead.read(b)!=-1 && !stop) {
				BaseDataPacket packet=new BaseDataPacket(clientFileDownloadCommand.getBusinessGroup(),b);
				ctx.writeAndFlush(packet);
				surplusLength-=1015;
				int bSize=(int)Math.min(1015,surplusLength);
				if(bSize<=0) {
					break;
				}
				b=new byte[bSize];
			}
			if(!stop) {
				ResoultCommand command=new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_PUSHFILE,"文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】传输完成！",true,clientFileDownloadCommand.getBusinessGroup());
				ctx.writeAndFlush(command);
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ResoultCommand command=new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_PUSHFILE,"文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】读取错误！"+e.getMessage(),false,clientFileDownloadCommand.getBusinessGroup());
			ctx.writeAndFlush(command);
			ServerHandler.cleanBusinessCommands(ctx.channel().remoteAddress().toString()+"_"+clientFileDownloadCommand.getBusinessGroup());
			logger.log(Level.WARNING, "文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】读取错误！", e);
			
		}finally {
			close();
		}
	}
	
	@Override
	public void close() {
		// TODO Auto-generated method stub
		stop=true;
		try {
			fileRead.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	public void hasPacket(ChannelHandlerContext ctx, BasePacket packet) {
		if(packet instanceof ResoultCommand) {
			ResoultCommand reCommandPacket = (ResoultCommand)packet;
			if(reCommandPacket.isStatus()) {
				//暂时没有需要支持的命令
			}else {
				//错误命令
				logger.log(Level.WARNING, "文件【"+clientFileDownloadCommand.getRemoteFilePath()+"】推送失败！客户端异常信息："+reCommandPacket.getMessage());
				close();
			}
		}
	}

}
